CONSTANT_Class = 7
CONSTANT_FieldRef = 9
CONSTANT_MethodRef = 10
CONSTANT_InterfaceMethodRef = 11
CONSTANT_String = 8
CONSTANT_Integer = 3
CONSTANT_Float = 4
CONSTANT_Long = 5
CONSTANT_Double = 6
CONSTANT_NameAndType = 12
CONSTANT_Utf8 = 1
CONSTANT_MethodHandle = 15
CONSTANT_MethodType = 16
CONSTANT_InvokeDynamic = 18


class ConstantInfo:
    def __init__(self):
        self.tag = 0

    def readInfo(self, clsReader):
        pass

    def setTag(self, tag):
        self.tag = tag


def readConstantInfo(clsReader, constantPool):
    tag = clsReader.readU8()
    info = newConstantInfo(tag, constantPool)
    info.readInfo(clsReader)
    return tag, info


def newConstantInfo(tag, constantPool):
    from classfile.cp_class import ConstantClassInfo
    from classfile.cp_invoke_dynamic import ConstantMethodTypeInfo, ConstantMethodHandleInfo, ConstantInvokeDynamicInfo
    from classfile.cp_member_info import ConstantFieldRefInfo, ConstantMethodRefInfo, ConstantInterfaceMethodInfo
    from classfile.cp_name_and_type import ConstantNameAndTypeInfo
    from classfile.cp_numberic import ConstantIntegerInfo, ConstantFloatInfo, ConstantLongInfo, ConstantDoubleInfo
    from classfile.cp_string import ConstantStringInfo
    from classfile.cp_utf8 import ConstantUTF8Info
    from classfile.cp_member_info import ConstantMemberRefInfo

    cpInfo = None
    if tag == CONSTANT_Integer:
        cpInfo = ConstantIntegerInfo()
    elif tag == CONSTANT_Float:
        cpInfo = ConstantFloatInfo()
    elif tag == CONSTANT_Long:
        cpInfo = ConstantLongInfo()
    elif tag == CONSTANT_Double:
        cpInfo = ConstantDoubleInfo()
    elif tag == CONSTANT_Utf8:
        cpInfo = ConstantUTF8Info()
    elif tag == CONSTANT_String:
        cpInfo = ConstantStringInfo(constantPool)
    elif tag == CONSTANT_Class:
        cpInfo = ConstantClassInfo(constantPool)
    elif tag == CONSTANT_FieldRef:
        cpInfo = ConstantFieldRefInfo(ConstantMemberRefInfo(constantPool))
    elif tag == CONSTANT_MethodRef:
        cpInfo = ConstantMethodRefInfo(ConstantMemberRefInfo(constantPool))
    elif tag == CONSTANT_InterfaceMethodRef:
        cpInfo = ConstantInterfaceMethodInfo(ConstantMemberRefInfo(constantPool))
    elif tag == CONSTANT_NameAndType:
        cpInfo = ConstantNameAndTypeInfo()
    elif tag == CONSTANT_MethodType:
        cpInfo = ConstantMethodTypeInfo()
    elif tag == CONSTANT_MethodHandle:
        cpInfo = ConstantMethodHandleInfo()
    elif tag == CONSTANT_InvokeDynamic:
        cpInfo = ConstantInvokeDynamicInfo()
    else:
        raise Exception("Unknown constant type")
    cpInfo.setTag(tag)
    return cpInfo

